package utils

import (
	"reflect"
)

// 利用反射将结构体转化为map
func StructToMap(obj interface{}) map[string]interface{} {
	obj1 := reflect.TypeOf(obj)
	obj2 := reflect.ValueOf(obj)

	var data = make(map[string]interface{})
	for i := 0; i < obj1.NumField(); i++ {
		data[obj1.Field(i).Name] = obj2.Field(i).Interface()
	}
	return data
}

func ListStructToMap(objs []interface{}) []map[string]interface{} {
	var datas []map[string]interface{}
	for _,obj:=range objs{
		datas=append(datas, StructToMap(obj))
	}
	return datas
}

func StructSliceToMapSlice(source interface{}) []map[string]interface{}{
	// 判断，interface转为[]interface{}
	res := make([]map[string]interface{}, 0)
	v := reflect.ValueOf(source)
	if v.Kind() != reflect.Slice {
		return res
	}
	l := v.Len()
	ret := make([]interface{}, l)
	for i := 0; i < l; i++ {
		ret[i] = v.Index(i).Interface()
	}

	// 通过遍历，每次迭代将struct转为map
	for _, elem := range ret {
		res = append(res, StructToMap(elem))
	}
	return res


}

//binding type interface 要修改的结构体
//value type interace 有数据的结构体
func StructAssign(binding interface{}, value interface{}) {

	bVal := reflect.ValueOf(binding).Elem() //获取reflect.Type类型
	vVal := reflect.ValueOf(value).Elem()   //获取reflect.Type类型
	vTypeOfT := vVal.Type()
	for i := 0; i < vVal.NumField(); i++ {

		// 在要修改的结构体中查询有数据结构体中相同属性的字段，有则修改其值
		name := vTypeOfT.Field(i).Name
		if ok := bVal.FieldByName(name).IsValid(); ok {

			bVal.FieldByName(name).Set(reflect.ValueOf(vVal.Field(i).Interface()))
		}
	}
}
